#ifndef NETLIB_TCPSERVER_H
#define NETLIB_TCPSERVER_H

// TCP服务类

#include "Atomic.h"
#include "Types.h"
#include "TcpConnection.h"

#include <map>

namespace netlib
{
namespace net
{

class Acceptor;
class EventLoop;
class EventLoopThreadPool;

class TcpServer : noncopyable // TCP服务类，不可拷贝
{
public:
    typedef std::function<void(EventLoop*)> ThreadInitCallback;
    enum Option
    {
        kNoReusePort,
        kReusePort,
    };

    TcpServer(EventLoop* loop,
                const InetAddress& listenAddr,
                const string& nameArg,
                Option option = kNoReusePort);

    ~TcpServer();

    const string& ipPort() const { return ipPort_; } // 返回服务端口

    const string& name() const { return name_; } // 返回服务名称

    EventLoop* getLoop() const { return loop_; } // 返回EventLoop对象指针

    void setThreadNum(int numThreads); // 设置线程池中线程的个数

    // 设置IO线程池的回调函数，loop()之前调用
    void setThreadInitCallback(const ThreadInitCallback& cb)
    { threadInitCallback_ = cb; }

    std::shared_ptr<EventLoopThreadPool> threadPool()
    { return threadPool_; }

    void start(); // 启动服务

    // 设置新连接到来的回调函数
    void setConnectionCallback(const ConnectionCallback& cb)
    { connectionCallback_ = cb; }

    // 设置消息到来的回调函数
    void setMessageCallback(const MessageCallback& cb)
    { messageCallback_ = cb; }

    // 设置写完成的回调函数
    void setWriteCompleteCallback(const WriteCompleteCallback& cb)
    { writeCompleteCallback_ = cb; }

private:
    void newConnection(int sockfd, const InetAddress& peerAddr);

    void removeConnection(const TcpConnectionPtr& conn);

    void removeConnectionInLoop(const TcpConnectionPtr& conn);

    typedef std::map<string, TcpConnectionPtr> ConnectionMap; // <连接名，连接对象指针>

    EventLoop* loop_;                       // acceptor_所属的EventLoop对象
    const string ipPort_;                   // 服务端口
    const string name_;                     // 服务名
    std::unique_ptr<Acceptor> acceptor_;                // 接受连接的对象
    std::shared_ptr<EventLoopThreadPool> threadPool_;   // IO线程池对象
    ConnectionCallback connectionCallback_;             // 连接到来的回调函数
    MessageCallback messageCallback_;                   // 消息到来的回调函数
    WriteCompleteCallback writeCompleteCallback_;       // 数据发送完毕回调函数
    ThreadInitCallback threadInitCallback_;             // IO线程池的回调函数
    AtomicInt32 started_;                   // 原子计数类，标志服务是否已经启动
    int nextConnId_;                        // 下一个连接ID
    ConnectionMap connections_;             // 连接列表

}; // class TcpServer end

} // namespace net end

} // namespace netlib end

#endif